package com.laundry.user.data.repository

import android.content.Context
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import com.laundry.user.data.api.*
import com.laundry.user.data.database.LaundryDatabase
import com.laundry.user.data.model.*

/**
 * 商家数据仓库
 */
class MerchantRepository(private val context: Context) {
    
    private val database = LaundryDatabase.getDatabase(context)
    private val apiService = NetworkModule.getApiService()
    
    // ==================== 服务分类 ====================
    
    /**
     * 获取服务分类列表
     */
    fun getServiceCategories(): Flow<List<ServiceCategory>> = flow {
        try {
            // 先发射本地数据
            database.serviceCategoryDao().getAllActiveCategories().collect { localCategories ->
                emit(localCategories)
            }
            
            // 然后从服务器同步
            val response = apiService.getServiceCategories()
            if (response.isSuccessful && response.body()?.success == true) {
                val categories = response.body()?.data ?: emptyList()
                // 更新本地数据库
                database.serviceCategoryDao().deleteAllCategories()
                database.serviceCategoryDao().insertCategories(categories)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
    
    // ==================== 商家相关 ====================
    
    /**
     * 获取商家列表
     */
    suspend fun getMerchants(
        page: Int = 1,
        size: Int = 20,
        categoryId: String? = null,
        latitude: Double? = null,
        longitude: Double? = null,
        radius: Int = 10000,
        keyword: String? = null,
        sort: String = "distance"
    ): Result<PagedResponse<Merchant>> {
        return try {
            val response = apiService.getMerchants(
                page = page,
                size = size,
                categoryId = categoryId,
                latitude = latitude,
                longitude = longitude,
                radius = radius,
                keyword = keyword,
                sort = sort
            )
            
            if (response.isSuccessful && response.body()?.success == true) {
                val pagedResponse = response.body()?.data
                if (pagedResponse != null) {
                    // 缓存商家数据到本地
                    if (page == 1) {
                        // 第一页时清空旧数据
                        database.merchantDao().deleteAllMerchants()
                    }
                    database.merchantDao().insertMerchants(pagedResponse.items)
                    Result.success(pagedResponse)
                } else {
                    Result.failure(Exception("商家数据为空"))
                }
            } else {
                Result.failure(Exception(response.body()?.message ?: "获取商家列表失败"))
            }
        } catch (e: Exception) {
            // 网络错误时返回本地缓存数据
            try {
                val localMerchants = if (keyword.isNullOrEmpty()) {
                    if (categoryId.isNullOrEmpty()) {
                        database.merchantDao().getAllVerifiedMerchants()
                    } else {
                        database.merchantDao().getMerchantsByCategory(categoryId)
                    }
                } else {
                    database.merchantDao().searchMerchants(keyword)
                }
                
                // 这里简化处理，实际应该实现本地分页
                val merchants = mutableListOf<Merchant>()
                localMerchants.collect { merchants.addAll(it) }
                
                val pagedResponse = PagedResponse(
                    items = merchants.take(size),
                    total = merchants.size,
                    page = page,
                    size = size,
                    pages = (merchants.size + size - 1) / size,
                    hasNext = merchants.size > page * size,
                    hasPrev = page > 1
                )
                Result.success(pagedResponse)
            } catch (localException: Exception) {
                Result.failure(e)
            }
        }
    }
    
    /**
     * 获取商家详情
     */
    suspend fun getMerchantDetail(merchantId: String): Result<Merchant> {
        return try {
            val response = apiService.getMerchantDetail(merchantId)
            
            if (response.isSuccessful && response.body()?.success == true) {
                val merchant = response.body()?.data
                if (merchant != null) {
                    // 更新本地缓存
                    database.merchantDao().insertMerchant(merchant)
                    Result.success(merchant)
                } else {
                    Result.failure(Exception("商家详情为空"))
                }
            } else {
                // 尝试从本地获取
                val localMerchant = database.merchantDao().getMerchantById(merchantId)
                if (localMerchant != null) {
                    Result.success(localMerchant)
                } else {
                    Result.failure(Exception(response.body()?.message ?: "获取商家详情失败"))
                }
            }
        } catch (e: Exception) {
            // 网络错误时从本地获取
            try {
                val localMerchant = database.merchantDao().getMerchantById(merchantId)
                if (localMerchant != null) {
                    Result.success(localMerchant)
                } else {
                    Result.failure(e)
                }
            } catch (localException: Exception) {
                Result.failure(e)
            }
        }
    }
    
    /**
     * 获取商家服务列表
     */
    suspend fun getMerchantServices(merchantId: String): Result<List<Service>> {
        return try {
            val response = apiService.getMerchantServices(merchantId)
            
            if (response.isSuccessful && response.body()?.success == true) {
                val services = response.body()?.data ?: emptyList()
                // 更新本地缓存
                database.serviceDao().deleteServicesByMerchant(merchantId)
                database.serviceDao().insertServices(services)
                Result.success(services)
            } else {
                Result.failure(Exception(response.body()?.message ?: "获取服务列表失败"))
            }
        } catch (e: Exception) {
            // 网络错误时从本地获取
            try {
                val localServices = mutableListOf<Service>()
                database.serviceDao().getServicesByMerchant(merchantId).collect {
                    localServices.addAll(it)
                }
                Result.success(localServices)
            } catch (localException: Exception) {
                Result.failure(e)
            }
        }
    }
    
    /**
     * 获取商家评价列表
     */
    suspend fun getMerchantReviews(
        merchantId: String,
        page: Int = 1,
        size: Int = 20
    ): Result<PagedResponse<Review>> {
        return try {
            val response = apiService.getMerchantReviews(merchantId, page, size)
            
            if (response.isSuccessful && response.body()?.success == true) {
                val pagedResponse = response.body()?.data
                if (pagedResponse != null) {
                    // 缓存评价数据（仅第一页）
                    if (page == 1) {
                        pagedResponse.items.forEach { review ->
                            database.reviewDao().insertReview(review)
                        }
                    }
                    Result.success(pagedResponse)
                } else {
                    Result.failure(Exception("评价数据为空"))
                }
            } else {
                Result.failure(Exception(response.body()?.message ?: "获取评价列表失败"))
            }
        } catch (e: Exception) {
            // 网络错误时从本地获取
            try {
                val localReviews = mutableListOf<Review>()
                database.reviewDao().getReviewsByMerchant(merchantId).collect {
                    localReviews.addAll(it)
                }
                
                val pagedResponse = PagedResponse(
                    items = localReviews.take(size),
                    total = localReviews.size,
                    page = page,
                    size = size,
                    pages = (localReviews.size + size - 1) / size,
                    hasNext = localReviews.size > page * size,
                    hasPrev = page > 1
                )
                Result.success(pagedResponse)
            } catch (localException: Exception) {
                Result.failure(e)
            }
        }
    }
    
    // ==================== 收藏相关 ====================
    
    /**
     * 添加收藏
     */
    suspend fun addFavorite(merchantId: String): Result<String> {
        return try {
            val request = AddFavoriteRequest(merchantId)
            val response = apiService.addFavorite(request)
            
            if (response.isSuccessful && response.body()?.success == true) {
                // 添加到本地数据库
                val merchant = database.merchantDao().getMerchantById(merchantId)
                if (merchant != null) {
                    val favorite = Favorite(
                        id = "${getCurrentUserId()}_$merchantId",
                        userId = getCurrentUserId(),
                        merchantId = merchantId,
                        merchantName = merchant.name,
                        merchantAvatar = merchant.avatar,
                        merchantRating = merchant.rating,
                        createdAt = getCurrentTime()
                    )
                    database.favoriteDao().insertFavorite(favorite)
                }
                Result.success("收藏成功")
            } else {
                Result.failure(Exception(response.body()?.message ?: "收藏失败"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 取消收藏
     */
    suspend fun removeFavorite(merchantId: String): Result<String> {
        return try {
            val response = apiService.removeFavorite(merchantId)
            
            if (response.isSuccessful && response.body()?.success == true) {
                // 从本地数据库删除
                database.favoriteDao().deleteFavorite(getCurrentUserId(), merchantId)
                Result.success("取消收藏成功")
            } else {
                Result.failure(Exception(response.body()?.message ?: "取消收藏失败"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 获取收藏列表
     */
    fun getFavorites(): Flow<List<Favorite>> = flow {
        try {
            // 先发射本地数据
            database.favoriteDao().getFavorites(getCurrentUserId()).collect { localFavorites ->
                emit(localFavorites)
            }
            
            // 然后从服务器同步
            val response = apiService.getFavorites()
            if (response.isSuccessful && response.body()?.success == true) {
                val pagedResponse = response.body()?.data
                if (pagedResponse != null) {
                    // 更新本地数据库
                    pagedResponse.items.forEach { favorite ->
                        database.favoriteDao().insertFavorite(favorite)
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
    
    /**
     * 检查是否已收藏
     */
    suspend fun isFavorite(merchantId: String): Boolean {
        return try {
            database.favoriteDao().isFavorite(getCurrentUserId(), merchantId)
        } catch (e: Exception) {
            false
        }
    }
    
    // ==================== 搜索相关 ====================
    
    /**
     * 保存搜索历史
     */
    suspend fun saveSearchHistory(keyword: String) {
        try {
            val userId = getCurrentUserId()
            val existing = database.searchHistoryDao().getSearchHistoryByKeyword(userId, keyword)
            
            if (existing != null) {
                // 更新搜索次数和时间
                val updated = existing.copy(
                    searchCount = existing.searchCount + 1,
                    lastSearchTime = getCurrentTime()
                )
                database.searchHistoryDao().updateSearchHistory(updated)
            } else {
                // 新增搜索记录
                val searchHistory = SearchHistory(
                    id = "${userId}_${System.currentTimeMillis()}",
                    userId = userId,
                    keyword = keyword,
                    searchCount = 1,
                    lastSearchTime = getCurrentTime()
                )
                database.searchHistoryDao().insertSearchHistory(searchHistory)
            }
            
            // 限制搜索历史数量
            database.searchHistoryDao().limitSearchHistory(userId, 20)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
    
    /**
     * 获取搜索历史
     */
    suspend fun getSearchHistory(limit: Int = 10): List<SearchHistory> {
        return try {
            database.searchHistoryDao().getSearchHistory(getCurrentUserId(), limit)
        } catch (e: Exception) {
            emptyList()
        }
    }
    
    /**
     * 清除搜索历史
     */
    suspend fun clearSearchHistory() {
        try {
            database.searchHistoryDao().clearSearchHistory(getCurrentUserId())
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
    
    // ==================== 工具方法 ====================
    
    private fun getCurrentUserId(): String {
        return context.getSharedPreferences("user_prefs", Context.MODE_PRIVATE)
            .getString("current_user_id", "") ?: ""
    }
    
    private fun getCurrentTime(): String {
        return java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss", java.util.Locale.getDefault())
            .format(java.util.Date())
    }
}
